#ifndef MOTOR_H_INCLUDED
#define MOTOR_H_INCLUDED

#include "act_types.h"
#include "mhdef.h"
#include "ccycle.h"
#include "feedback.h"
#include "timer.h"
#include "udp.h"

#define MNUM    12
#define GNUM    (MNUM / 2)

typedef struct _MOTOR MOTOR;

struct _MOTOR
{
    short pos[2][MNUM];             /* 0-11: q1,q2,h1,h2,q3,q4,h3,h4,qxk,hxk,qxk2,hxk2
                                        0-左机头；1-右机头
                                    */
    uchar group_state[10];
    short pos_bk[2][MNUM];          /* 备份状态 */

    CCYCLE cycle;
    CCYCLE reset_cycle;
    CHECK_TIMER timer;

    BOOL reset_all;             /* 是否全部复位 */
    BOOL restore;               /* 是否恢复状态 */
    BOOL sink_enable;           /* 辛克使能 */
    short setting_pos[2];       /* 0-度目设置位置;1-辛克设置位置 */

    int (*reset)(MH_UDP *pudp, int type, short *find_zero, int num);
    int (*exec)(MH_UDP *pudp, int type, short *delta, short *find_zero, int num);
};


MOTOR *motor_new();
void motor_set_cycle(MOTOR *motor, CCYCLE *cycle, CCYCLE *reset_cycle);
int motor_exec(MH_UDP *pudp, MOTOR *motor, ActType type);
int motor_exec_cycle(MH_UDP *pudp, void *user_data);
void motor_start_timer(MOTOR *motor, TIMEOUT_FUNC pfunc, BOOL now);
int motor_exec_timer(MH_UDP *pudp, MOTOR *motor);
void motor_stop_cycle(MOTOR *motor);
int motor_check_error(MH_UDP *pudp, void *user_data);

void motor_setting_pos(MOTOR *motor, short dumu_pos, short sink_pos);
BOOL motor_reset_complete(MOTOR *motor);
BOOL motor_restore_complete(MOTOR *motor);

void motor_convert_pos(MOTOR *motor, short *pos_in, short *pos_out);
void motor_set_pos(MOTOR *motor, short *pos, int num);
void motor_get_pos(MOTOR *motor, short *pos, int num);
int motor_encount_error(MOTOR *motor, FEEDBACK *fb, CCYCLE *cycle);
void motor_set_restore(MOTOR *motor, BOOL restore);
void motor_set_reset_all(MOTOR *motor, BOOL reset_all);
void motor_set_sink_enable(MOTOR *motor, BOOL enable);

CCYCLE* motor_get_cycle(MOTOR *motor);
BOOL motor_need_restore(MOTOR *motor);

void motor_set_group_state(MOTOR *motor, short pos, int group);
short motor_get_group_state(MOTOR *motor, int group);
int motor_exec_group(MH_UDP *pudp, MOTOR *motor, int group);

#endif // MOTOR_H_INCLUDED
